/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * vim: set ts=8 sts=4 et sw=4 tw=99: * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */#include"vm/ErrorReporting.h"#include"mozilla/Move.h"#include<stdarg.h>#include"jscntxt.h"#include"jsexn.h"#include"jsfriendapi.h"#include"jscntxtinlines.h"usingmozilla::Move;usingJS::HandleObject;usingJS::HandleValue;usingJS::UniqueTwoByteChars;voidjs::CallWarningReporter(JSContext*cx,JSErrorReport*reportp){MOZ_ASSERT(reportp);MOZ_ASSERT(JSREPORT_IS_WARNING(reportp->flags));if(JS::WarningReporterwarningReporter=cx->runtime()->warningReporter)warningReporter(cx,reportp);}voidjs::CompileError::throwError(JSContext*cx){if(JSREPORT_IS_WARNING(flags)){CallWarningReporter(cx,this);return;}// If there's a runtime exception type associated with this error// number, set that as the pending exception. For errors occuring at// compile time, this is very likely to be a JSEXN_SYNTAXERR.//// If an exception is thrown but not caught, the JSREPORT_EXCEPTION// flag will be set in report.flags. Proper behavior for an error// reporter is to ignore a report with this flag for all but top-level// compilation errors. The exception will remain pending, and so long// as the non-top-level "load", "eval", or "compile" native function// returns false, the top-level reporter will eventually receive the// uncaught exception report.ErrorToException(cx,this,nullptr,nullptr);}booljs::ReportCompileWarning(JSContext*cx,ErrorMetadata&&metadata,UniquePtr<JSErrorNotes>notes,unsignedflags,unsignederrorNumber,va_listargs){// On the active thread, report the error immediately. When compiling off// thread, save the error so that the thread finishing the parse can report// it later.CompileErrortempErr;CompileError*err=&tempErr;if(cx->helperThread()&&!cx->addPendingCompileError(&err))returnfalse;err->notes=Move(notes);err->flags=flags;err->errorNumber=errorNumber;err->filename=metadata.filename;err->lineno=metadata.lineNumber;err->column=metadata.columnNumber;err->isMuted=metadata.isMuted;if(UniqueTwoByteCharslineOfContext=Move(metadata.lineOfContext))err->initOwnedLinebuf(lineOfContext.release(),metadata.lineLength,metadata.tokenOffset);if(!ExpandErrorArgumentsVA(cx,GetErrorMessage,nullptr,errorNumber,nullptr,ArgumentsAreLatin1,err,args)){returnfalse;}if(!cx->helperThread())err->throwError(cx);returntrue;}voidjs::ReportCompileError(JSContext*cx,ErrorMetadata&&metadata,UniquePtr<JSErrorNotes>notes,unsignedflags,unsignederrorNumber,va_listargs){// On the active thread, report the error immediately. When compiling off// thread, save the error so that the thread finishing the parse can report// it later.CompileErrortempErr;CompileError*err=&tempErr;if(cx->helperThread()&&!cx->addPendingCompileError(&err))return;err->notes=Move(notes);err->flags=flags;err->errorNumber=errorNumber;err->filename=metadata.filename;err->lineno=metadata.lineNumber;err->column=metadata.columnNumber;err->isMuted=metadata.isMuted;if(UniqueTwoByteCharslineOfContext=Move(metadata.lineOfContext))err->initOwnedLinebuf(lineOfContext.release(),metadata.lineLength,metadata.tokenOffset);if(!ExpandErrorArgumentsVA(cx,GetErrorMessage,nullptr,errorNumber,nullptr,ArgumentsAreLatin1,err,args)){return;}if(!cx->helperThread())err->throwError(cx);}namespace{classMOZ_STACK_CLASSReportExceptionClosure:publicjs::ScriptEnvironmentPreparer::Closure{public:explicitReportExceptionClosure(HandleValue&exn):exn_(exn){}booloperator()(JSContext*cx)override{cx->setPendingException(exn_);returnfalse;}private:HandleValue&exn_;};}// anonymous namespacevoidjs::ReportErrorToGlobal(JSContext*cx,HandleObjectglobal,HandleValueerror){MOZ_ASSERT(!cx->isExceptionPending());#ifdef DEBUG// No assertSameCompartment version that doesn't take JSContext...if(error.isObject()){AssertSameCompartment(global,&error.toObject());}#endif // DEBUGReportExceptionClosurereport(error);PrepareScriptEnvironmentAndInvoke(cx,global,report);}